/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "gmock/gmock-actions.h"
#include "mockcpp/mockcpp.hpp"
#include "eSDKOBS.h"
#include "ObjectStorageBackupJob.h"
#include "interface/CloudServiceResponse.h"
#include "interface/CloudServiceRequest.h"
#include "parser/BucketLogParser.h"

using namespace OBSPlugin;

class ObjectStorageBucketLogIncTest : public testing::Test {
public:
    void SetUp() {};
    void TearDown()
    {
        GlobalMockObject::verify();
    };
};

/*
 * 用例名称：判断是否为日志增量备份
 * 前置条件：无
 * check点：返回成功
 */
TEST_F(ObjectStorageBucketLogIncTest, IsBucketLogInc)
{
    OBSPlugin::ObjectStorageBackupJob backupjob;
    backupjob.m_backupJobPtr = std::make_shared<AppProtect::BackupJob>();

    backupjob.m_backupJobPtr->jobParam.backupType = AppProtect::BackupJobType::FULL_BACKUP;
    EXPECT_EQ(backupjob.IsBucketLogInc(), false);

    backupjob.m_backupJobPtr->jobParam.backupType = AppProtect::BackupJobType::INCREMENT_BACKUP;
    backupjob.m_protectedOBS.advParms.m_useBucketLog = "false";
    EXPECT_EQ(backupjob.IsBucketLogInc(), false);

    backupjob.m_protectedOBS.advParms.m_useBucketLog = "true";
    EXPECT_EQ(backupjob.IsBucketLogInc(), true);
}

/*
 * 用例名称：获取桶日志
 * 前置条件：无
 * check点：返回成功
 */
TEST_F(ObjectStorageBucketLogIncTest, GetBucketLogs)
{
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::IsBucketLogInc)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::QueryPreviousCopy)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER(Module::JsonHelper::JsonStringToStruct<OBSPlugin::BackupObjectInfosInCopy>)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::InitCloudClient)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::PrepareBucketLog)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::ParseBucketLog)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::UpdateGeneralResource)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));

    OBSPlugin::ObjectStorageBackupJob backupjob;
    backupjob.m_backupJobPtr = std::make_shared<AppProtect::BackupJob>();
    OBSProtectSubObject object;
    backupjob.m_protectedOBS.obsProtectSubObjectList.emplace_back(object);

    EXPECT_EQ(backupjob.GetBucketLogs(), true);
    EXPECT_EQ(backupjob.GetBucketLogs(), false);
    EXPECT_EQ(backupjob.GetBucketLogs(), false);
    EXPECT_EQ(backupjob.GetBucketLogs(), false);
    EXPECT_EQ(backupjob.GetBucketLogs(), false);
    EXPECT_EQ(backupjob.GetBucketLogs(), false);
    EXPECT_EQ(backupjob.GetBucketLogs(), false);
    EXPECT_EQ(backupjob.GetBucketLogs(), true);
}

Module::OBSResult GetBucketLogConfigSuccess(
    Module::HWCloudService*,
    const std::unique_ptr<Module::GetBucketLogConfigRequest>& request,
    std::unique_ptr<Module::GetBucketLogConfigResponse>& resp)
{
    resp = std::make_unique<Module::GetBucketLogConfigResponse>();
    resp->targetBucket = "targetBucket";
    Module::OBSResult result;
    result.result = Module::ResultType::SUCCESS;
    return result;
}

/*
 * 用例名称：获取桶日志
 * 前置条件：无
 * check点：返回成功
 */
TEST_F(ObjectStorageBucketLogIncTest, PrepareBucketLog)
{
    Module::StorageVerifyInfo verifyInfo;
    Module::HWCloudService hwCloudService(verifyInfo, obs_auth_switch::OBS_S3_TYPE);
    MOCKER_CPP_VIRTUAL(hwCloudService, &Module::HWCloudService::GetBucketLogConfig)
        .stubs()
        .will(invoke(GetBucketLogConfigSuccess));
    MOCKER(OBSPlugin::Remove)
        .stubs()
        .will(returnValue(true));
    MOCKER(OBSPlugin::RecurseCreateDirectory)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::DownloadAllBucketLog)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));

    OBSPlugin::ObjectStorageBackupJob backupjob;
    backupjob.m_backupJobPtr = std::make_shared<AppProtect::BackupJob>();
    Module::StorageConfig storageConfig;
    storageConfig.storageType = Module::StorageType::HUAWEI;
    backupjob.m_cloudClient = Module::CloudServiceManager::CreateInst(storageConfig);

    EXPECT_EQ(backupjob.PrepareBucketLog("", ""), false);
    EXPECT_EQ(backupjob.PrepareBucketLog("", ""), false);
    EXPECT_EQ(backupjob.PrepareBucketLog("", ""), true);
}

Module::OBSResult ListObjectsRequestSuccess(
    Module::HWCloudService*,
    const std::unique_ptr<Module::ListObjectsRequest>& request,
    std::unique_ptr<Module::ListObjectsResponse>& resp)
{
    resp = std::make_unique<Module::ListObjectsResponse>();
    Module::ListObjectsContent listObjectsContent;
    resp->contents.emplace_back(listObjectsContent);
    Module::OBSResult result;
    result.result = Module::ResultType::SUCCESS;
    return result;
}

/*
 * 用例名称：下载全部桶日志
 * 前置条件：无
 * check点：返回成功
 */
TEST_F(ObjectStorageBucketLogIncTest, DownloadAllBucketLog)
{
    Module::StorageVerifyInfo verifyInfo;
    Module::HWCloudService hwCloudService(verifyInfo, obs_auth_switch::OBS_S3_TYPE);
    MOCKER_CPP_VIRTUAL(hwCloudService, &Module::HWCloudService::ListObjects)
        .stubs()
        .will(invoke(ListObjectsRequestSuccess));
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::DownloadOneBucketLog)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER_CPP(&Module::FileNameListParser::WriteEntry)
        .stubs()
        .will(returnValue(Module::CTRL_FILE_RETCODE::FAILED))
        .then(returnValue(Module::CTRL_FILE_RETCODE::SUCCESS));

    OBSPlugin::ObjectStorageBackupJob backupjob;
    backupjob.m_backupJobPtr = std::make_shared<AppProtect::BackupJob>();
    Module::StorageConfig storageConfig;
    storageConfig.storageType = Module::StorageType::HUAWEI;
    backupjob.m_cloudClient = Module::CloudServiceManager::CreateInst(storageConfig);

    auto fileNameListParser = std::make_unique<Module::FileNameListParser>("");
    EXPECT_EQ(backupjob.DownloadAllBucketLog("", "", "", "", fileNameListParser), false);
    EXPECT_EQ(backupjob.DownloadAllBucketLog("", "", "", "", fileNameListParser), false);
    EXPECT_EQ(backupjob.DownloadAllBucketLog("", "", "", "", fileNameListParser), true);
}

Module::OBSResult MultiPartDownloadObjectSuccess(
    Module::HWCloudService*,
    const std::unique_ptr<Module::MultiPartDownloadObjectRequest>& request,
    std::unique_ptr<Module::MultiPartDownloadObjectResponse>& resp)
{
    Module::OBSResult result;
    result.result = Module::ResultType::SUCCESS;
    return result;
}

/*
 * 用例名称：下载单个桶日志
 * 前置条件：无
 * check点：返回成功
 */
TEST_F(ObjectStorageBucketLogIncTest, DownloadOneBucketLog)
{
    Module::StorageVerifyInfo verifyInfo;
    Module::HWCloudService hwCloudService(verifyInfo, obs_auth_switch::OBS_S3_TYPE);
    MOCKER_CPP_VIRTUAL(hwCloudService, &Module::HWCloudService::MultiPartDownloadObject)
        .stubs()
        .will(invoke(MultiPartDownloadObjectSuccess));

    OBSPlugin::ObjectStorageBackupJob backupjob;
    backupjob.m_backupJobPtr = std::make_shared<AppProtect::BackupJob>();
    Module::StorageConfig storageConfig;
    storageConfig.storageType = Module::StorageType::HUAWEI;
    backupjob.m_cloudClient = Module::CloudServiceManager::CreateInst(storageConfig);

    EXPECT_EQ(backupjob.DownloadOneBucketLog("", "", "", ""), true);
}

/*
 * 用例名称：解析桶日志
 * 前置条件：无
 * check点：返回成功
 */
TEST_F(ObjectStorageBucketLogIncTest, ParseBucketLog)
{
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::IsBucketLogInc)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER(OBSPlugin::Remove)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER(OBSPlugin::RecurseCreateDirectory)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));
    MOCKER_CPP(&Module::BucketLogParser::TraverseAllLogFiles)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));

    OBSPlugin::ObjectStorageBackupJob backupjob;

    OBSProtectSubObject object;
    EXPECT_EQ(backupjob.ParseBucketLog(object), true);
    EXPECT_EQ(backupjob.ParseBucketLog(object), false);
    EXPECT_EQ(backupjob.ParseBucketLog(object), false);
    EXPECT_EQ(backupjob.ParseBucketLog(object), true);
}

/*
 * 用例名称：查询父前缀
 * 前置条件：无
 * check点：返回成功
 */
TEST_F(ObjectStorageBucketLogIncTest, FindParentPrefix)
{
    MOCKER_CPP(&OBSPlugin::ObjectStorageBackupJob::IsBucketLogInc)
        .stubs()
        .will(returnValue(false))
        .then(returnValue(true));

    OBSPlugin::ObjectStorageBackupJob backupjob;

    PrefixInfo prefixInfo;
    EXPECT_EQ(backupjob.FindParentPrefix(prefixInfo), std::string(""));

    prefixInfo.subPrefixs.emplace_back("/abc/def");
    prefixInfo.parentPrefixFilter.emplace_back("/abc");
    EXPECT_EQ(backupjob.FindParentPrefix(prefixInfo), std::string("/abc"));
}